ReImplementInLua
ReImplementInLua.cs
using UnityEngine;
using System.Collections;
using XLua;
[GCOptimize(OptimizeFlag.PackAsTable)]
public struct PushAsTableStruct
{
public int x;
public int y;
}
public class ReImplementInLua : MonoBehaviour {
// Use this for initialization
void Start () {
LuaEnv luaenv = new LuaEnv();
//这两个例子都必须生成代码才能正常运行
//例子1:改造Vector3
//沿用Vector3原来的映射方案Vector3 -> userdata,但是把Vector3的方法实现改为lua实现,通过xlua.genaccessor实现不经过C#直接操作内存
//改为不经过C#的好处是性能更高,而且你可以省掉相应的生成代码以达成省text段的效果
//映射仍然沿用的好处是userdata比table更省内存,但操作字段比table性能稍低,当然,你也可以结合例子2的思路,把Vector3也改为映射到table
luaenv.DoString(@"
function test_vector3(title, v1, v2)
print(title)
print(v1.x, v1.y, v1.z)
print(v1, v2)
print(v1 + v2)
v1:Set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z)
print(v1)
print(CS.UnityEngine.Vector3.Normalize(v1))
end
test_vector3('----before change metatable----', CS.UnityEngine.Vector3(1, 2, 3), CS.UnityEngine.Vector3(7, 8, 9))
local get_x, set_x = xlua.genaccessor(0, 8)
local get_y, set_y = xlua.genaccessor(4, 8)
local get_z, set_z = xlua.genaccessor(8, 8)
local fields_getters = {
x = get_x, y = get_y, z = get_z
}
local fields_setters = {
x = set_x, y = set_y, z = set_z
}
local ins_methods = {
Set = function(o, x, y, z)
set_x(o, x)
set_y(o, y)
set_z(o, z)
end
}
local mt = {
__index = function(o, k)
--print('__index', k)
if ins_methods[k] then return ins_methods[k] end
return fields_getters[k] and fields_getters[k](o)
end,
__newindex = function(o, k, v)
return fields_setters[k] and fields_setters[k](o, v) or error('no such field ' .. k)
end,
__tostring = function(o)
return string.format('vector3 { %f, %f, %f}', o.x, o.y, o.z)
end,
__add = function(a, b)
return CS.UnityEngine.Vector3(a.x + b.x, a.y + b.y, a.z + b.z)
end
}
xlua.setmetatable(CS.UnityEngine.Vector3, mt)
test_vector3('----after change metatable----', CS.UnityEngine.Vector3(1, 2, 3), CS.UnityEngine.Vector3(7, 8, 9))
");
Debug.Log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
//例子2:struct映射到table改造
//PushAsTableStruct传送到lua侧将会是table,例子里头还为这个table添加了一个成员方法SwapXY,静态方法Print,打印格式化,以及构造函数
luaenv.DoString(@"
local mt = {
__index = {
SwapXY = function(o) --成员函数
o.x, o.y = o.y, o.x
end
},
__tostring = function(o) --打印格式化函数
return string.format('struct { %d, %d}', o.x, o.y)
end,
}
xlua.setmetatable(CS.PushAsTableStruct, mt)
local PushAsTableStruct = {
Print = function(o) --静态函数
print(o.x, o.y)
end
}
setmetatable(PushAsTableStruct, {
__call = function(_, x, y) --构造函数
return setmetatable({x = x, y = y}, mt)
end
})
xlua.setclass(CS, 'PushAsTableStruct', PushAsTableStruct)
");
PushAsTableStruct test;
test.x = 100;
test.y = 200;
luaenv.Global.Set("from_cs", test);
luaenv.DoString(@"
print('--------------from csharp---------------------')
assert(type(from_cs) == 'table')
print(from_cs)
CS.PushAsTableStruct.Print(from_cs)
from_cs:SwapXY()
print(from_cs)
print('--------------from lua---------------------')
local from_lua = CS.PushAsTableStruct(4, 5)
assert(type(from_lua) == 'table')
print(from_lua)
CS.PushAsTableStruct.Print(from_lua)
from_lua:SwapXY()
print(from_lua)
");
luaenv.Dispose();
}
// Update is called once per frame
void Update () {
}
}
🔚